package main.userInterface;

import javax.swing.*;
import java.io.*;
import java.awt.*;

import main.demonutils.io.IOController;
import main.model.island.IslandInterface;
import main.userInterface.islandui.IslandFrame;

/**
 * This class runs the simulation
 * 
 * @author Gabe
 * @version 02.01
 */
public class RunPanel extends JPanel{
	IOController io;
	//IOFrame ioFrame;
	
    IslandInterface island; //Stores the terrain
    IslandFrame islandFrame;
    
    final int xDIM = 17; final int yDIM = 10; //Default sizes for when no island is avalible
    int MnsPDy; //Minutes per day for calibrating the progress bar sunset
    int progress = 0; //Current position of the progress bar sunset
    JProgressBar sunset; //Visual representation of progress through days
    JLabel time; //The current time of day
    java.util.Timer tick = new java.util.Timer(true); //The ticker for timing days
    JSlider tickSlider; //A slider for setting the speed of the day
    int TICKspd = 50; //Tick speed with default 50
    boolean pausedboolean = true; //Is the day paused (days pause when they end unless continuous is true
    JButton start = new JButton("Start");
    JCheckBox continuousBx = new JCheckBox("Continuous Play");
    boolean continuous = false; //Next day starts automaticaly if true
    
    JLabel dirLab;
    JList choicesArea;
    JButton chooseDir = new JButton("Choose Directory");
    
    File loadedDirectory = null;
    File[] dirContent = null;
    File loadedIsland = null;
    boolean editedBoo = false;
    String[] extensions = {"ter","cri","isl"};
    JLabel loadStatus = new JLabel();
    JLabel editStatus = new JLabel();

    JCheckBox terB = new JCheckBox("*.ter");
    JCheckBox criB = new JCheckBox("*.cri");
    JCheckBox islB  = new JCheckBox("*.isl");
    
    //A set of buttons for save/load options on the island
    JButton loadIsBut = new JButton("Load HexIsland");
    JButton loadCrBut = new JButton("Load Critters");
    JButton saveCrBut = new JButton("Save Current Critters");
    JButton saveCrAsBut = new JButton("Save Current Critters as ...");
    JButton saveSeBut = new JButton("Save Session");
    JButton saveSeAsBut = new JButton("Save Session as ...");
    
    JTextArea logBox;//A display area to show messages about the island
    JTable critterTable; //Table of critter data
    String[] columnNames = {"Critter #","Sex","Health","X","Y"};
    Object[][] tableData; //Data on critters and positions for display


    public RunPanel(IOController io){
        setLayout(new BorderLayout());
        /*
        this.io = io;

        ioFrame = new IOFrame(io);
        
        //Define Data and Data Editors

        loadedDirectory = io.getCurrentDir();
        //TER = RIO.loadTerrain(); //Load terrain
        //CRI = new Critters();
        //CRI.loadCritters(15,TER.getX(),TER.getY());
        //iRun = new IslandRun(TER, CRI); //new iRun with terrain
        //iFrame = new IslandFrame(TER, CRI); //load the iFrame with terrain and critters
        //iFrame.setGridLine(false);//Gridlines off
        
        //TOOLS PAN
        JPanel toolsPan = new JPanel();
        toolsPan.setLayout(new BoxLayout(toolsPan,BoxLayout.PAGE_AXIS));
        //time = new JLabel("Time: "+iRun.getTime());
        //MnsPDy = iRun.getMnsPDy();
        //sunset = new JProgressBar(0, MnsPDy);
        JPanel tickPan = new JPanel();
        JLabel tickSlw = new JLabel("Slow");
        JLabel tickFst = new JLabel("Fast");
        tickSlider = new JSlider(JSlider.HORIZONTAL,10,200,TICKspd);
        tickSlider.setInverted(true);
        tickPan.add(tickSlw);
        tickPan.add(tickSlider);
        tickPan.add(tickFst);
        
        toolsPan.add(time);
        toolsPan.add(sunset);
        toolsPan.add(tickPan);
        JPanel runTools = new JPanel();  
        runTools.add(start);
        runTools.add(continuousBx);
        toolsPan.add(runTools);
        toolsPan.setBorder( BorderFactory.createCompoundBorder( BorderFactory.createCompoundBorder(
        BorderFactory.createTitledBorder("Run Tools"), BorderFactory.createEmptyBorder(0,0,0,0)), toolsPan.getBorder()));
        
        //SETUP PAN
        JPanel setupPan = new JPanel();
        setupPan.setLayout(new BoxLayout(setupPan,BoxLayout.PAGE_AXIS));

        JPanel filesPan = new JPanel(new BorderLayout());
        JPanel loadPan = new JPanel();
        loadPan.setLayout(new BoxLayout(loadPan,BoxLayout.PAGE_AXIS));
        
        JPanel loadLabPan = new JPanel(new GridLayout(0,1,0,0));
        JLabel dirIntroLab = new JLabel("The current directory is:");
        dirLab = new JLabel(RIO.getFileString(loadedDirectory));
        JLabel explainLab = new JLabel("This Directory contains the following selected files:");
        loadLabPan.add(dirIntroLab);
        loadLabPan.add(dirLab);
        loadLabPan.add(explainLab);
        
        JPanel fileTypePan = new JPanel();
        terB.setSelected(true); criB.setSelected(true); islB.setSelected(true);
        fileTypePan.add(terB); fileTypePan.add(criB); fileTypePan.add(islB);
        
        loadPan.add(loadLabPan);
        loadPan.add(fileTypePan);
        loadPan.setAlignmentX(Component.RIGHT_ALIGNMENT);
        
        JPanel loadChoicesPan = new JPanel();
        loadChoicesPan.setLayout(new BoxLayout(loadChoicesPan,BoxLayout.PAGE_AXIS));
        choicesArea = new JList();
        choicesArea.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        choicesArea.setLayoutOrientation(JList.VERTICAL);
        JScrollPane choicesScroll = new JScrollPane(choicesArea);
        choicesScroll.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
        choicesScroll.setAlignmentX(Component.CENTER_ALIGNMENT);
        chooseDir.setAlignmentX(Component.RIGHT_ALIGNMENT);
        loadChoicesPan.add(choicesScroll);
        loadChoicesPan.add(chooseDir);
        
        filesPan.add(loadPan, BorderLayout.PAGE_START);
        filesPan.add(loadChoicesPan, BorderLayout.CENTER);
        filesPan.setBorder(BorderFactory.createCompoundBorder( BorderFactory.createCompoundBorder(
        BorderFactory.createTitledBorder("Choose Directory and Files"), BorderFactory.createEmptyBorder(5,5,5,5)), filesPan.getBorder()));
        
        JPanel setupButPan = new JPanel(new GridLayout(0,1));
        setupButPan.add(loadIsBut);
        setupButPan.add(loadCrBut);
        setupButPan.add(saveCrBut);
        setupButPan.add(saveCrAsBut);
        setupButPan.add(saveSeBut);
        setupButPan.add(saveSeAsBut);
        setupButPan.setBorder(BorderFactory.createCompoundBorder( BorderFactory.createCompoundBorder(
        BorderFactory.createTitledBorder("Saving Options"), BorderFactory.createEmptyBorder(5,5,5,5)), setupButPan.getBorder()));
        
        setupPan.add(filesPan);
        setupPan.add(setupButPan);
        
        updateFileView();
        
        
        //SETTINGS PAN
        JPanel settingsPan = new JPanel();
        settingsPan.setLayout(new BoxLayout(settingsPan,BoxLayout.PAGE_AXIS));
        JPanel logPan = new JPanel(new GridLayout(0,1));
        logBox = new JTextArea(9,0);
        logBox.setEditable(false);
        logBox.setLineWrap(true);
        logBox.setWrapStyleWord(true);
        logBox.setFont(new Font("sansserif", Font.PLAIN, 14));
        JScrollPane logScroll = new JScrollPane(logBox);
        logBox.setText(iRun.getLog());
        logScroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
        logPan.add(logScroll);
        logPan.setBorder( BorderFactory.createCompoundBorder( BorderFactory.createCompoundBorder(
        BorderFactory.createTitledBorder("HexIsland Log"), BorderFactory.createEmptyBorder(0,5,5,5)), logPan.getBorder()));
        settingsPan.add(logPan);
        
        //CRITTER Pan
        JPanel critterPan = new JPanel();
        critterPan.setLayout(new BoxLayout(critterPan,BoxLayout.PAGE_AXIS));
        JPanel critterList = new JPanel(new BorderLayout());
        tableData = CRI.crittersTable(false);
        critterTable = new JTable(new CritterTableModel(tableData));
        TableColumn column = critterTable.getColumnModel().getColumn(0);
        column.setPreferredWidth(70);
        int settingsWidth = column.getPreferredWidth()*columnNames.length;
        critterTable.setAutoCreateRowSorter(true);
        critterTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        setSelectedRow(CRI.getTrackCRI());
        JScrollPane critterScroll = new JScrollPane(critterTable);
        critterScroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
        critterList.add(critterScroll,BorderLayout.CENTER);
        critterList.setBorder( BorderFactory.createCompoundBorder( BorderFactory.createCompoundBorder(
        BorderFactory.createTitledBorder("Critter List"), BorderFactory.createEmptyBorder(5,5,5,5)), critterList.getBorder()));
        critterPan.add(critterList);

        setupPan.setPreferredSize(new Dimension(settingsWidth,0));
        settingsPan.setPreferredSize(new Dimension(settingsWidth,0));
        critterPan.setPreferredSize(new Dimension(settingsWidth,0));
        
        JTabbedPane islandTabPane = new JTabbedPane();
        islandTabPane.addTab("Setup", null, setupPan ,"Edits the island.");
        islandTabPane.addTab("Event Log", null, settingsPan,"Logs major events on the island.");
        islandTabPane.addTab("Critter Stats", null, critterPan,"Edits the island.");
        
        JPanel sideBar = new JPanel();
        sideBar.setLayout(new BorderLayout());
        sideBar.add(toolsPan, BorderLayout.NORTH);
        sideBar.add(islandTabPane, BorderLayout.CENTER);
        
        add(iFrame, BorderLayout.CENTER);
        add(sideBar, BorderLayout.EAST);
        
        
        //Action Listeners
        tickSlider.addChangeListener(new ChangeListener(){
            public void stateChanged(ChangeEvent e){
                TICKspd = tickSlider.getValue();
            }
        });
        continuousBx.addChangeListener(new ChangeListener(){
            public void stateChanged(ChangeEvent e){
                continuous = continuousBx.isSelected();
            }
        });
        terB.addActionListener(new ActionListener(){ 
            public void actionPerformed(ActionEvent e){
                updateFileView();
            }
        });
        criB.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e){
                updateFileView();
            }
        });
        islB.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e){
                updateFileView();
            }
        });
        chooseDir.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent ae){
                File f = RIO.chooseDirectory();
                if(f != null){loadedDirectory = f;}
                updateFileView();
            } 
        });
        loadIsBut.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent ae){
                if(choicesArea.getSelectedIndex() >= 0 && choicesArea.getSelectedIndex() < dirContent.length){
                    int n = JOptionPane.showConfirmDialog(null,
                    "Loading will delete the current changes made to this island."
                    +"\nThe critters will be unaffected and continue with their lives."
                    +"\nWould you like to continue?",
                    "HexIsland progress will be lost",JOptionPane.YES_NO_OPTION);
                    if(n==0){
                        TER = RIO.loadTerrain(dirContent[choicesArea.getSelectedIndex()]);
                        iFrame.setTER(TER);
                        iRun.setTER(TER);
                        loadedIsland = TER.getLI();
                        stepUp();
                        updateFileView();
                    }
                }else{
                    JOptionPane.showMessageDialog(null, "No file has been selected to load.");
                }
            }
        });
        
        critterTable.getSelectionModel().addListSelectionListener(new ListSelectionListener(){
            public void valueChanged(ListSelectionEvent e){
                if(!e.getValueIsAdjusting()){ //Ignore imput whilst adjusting
                    ListSelectionModel lsm = (ListSelectionModel)e.getSource(); //get the mode
                    int viewIndex = lsm.getMaxSelectionIndex(); //-1 if empty
                    if(viewIndex == -1){ //Default when empty
                        setSelectedRow(CRI.getTrackCRI()); //Use the selectedRow function to apply the trackCRI
                    }else{
                        int modelIndex = critterTable.convertRowIndexToModel(viewIndex);
                        int track = Integer.parseInt(tableData[modelIndex][0].toString());
                        setSelectedCritter(track);
                    }
                }
            }
        });
        
        start.addActionListener(new ActionListener(){ 
            public void actionPerformed(ActionEvent ae){
                //Pressing Start will change the status of the button as signified by the paused boolean
                if(pausedboolean){ //is the run paused? run this if begining in a paused state (turning on)
                    pausedboolean = false; //unpause
                    start.setText("Pause"); //Give pause option text
                    tickSlider.setEnabled(false);
                    tick.scheduleAtFixedRate(new TimerTask(){
                        public void run(){
                            stepUp();
                            if(progress>=MnsPDy){ //Check if day has finished
                                progress=0;
                                setTable();
                                if(!continuous){
                                    tickSlider.setEnabled(true);
                                    start.setText("Start");
                                    pausedboolean = true;
                                    cancel();
                                }
                            }
                            if(pausedboolean){ //Check if day is paused
                                tickSlider.setEnabled(true);
                                setTable();
                                start.setText("Start");
                                cancel();
                            }
                        }
                    } ,0,TICKspd);
                }else{pausedboolean = true;}
            }
        }); */

    }
    
    /**
     * Updates the list of files to display
     */
    /*public void updateFileView(){
        if(!RIO.fileExists(loadedDirectory)){
            loadedDirectory = RIO.getCurrentDir();
        }
        dirLab.setText(RIO.getFileString(loadedDirectory));
        String e = "";
        if(terB.isSelected()){e += "ter;";}
        if(criB.isSelected()){e += "cri;";}
        if(islB.isSelected()){e +="isl;";}
        String[]extensions = e.split(";");
        //System.out.print("\nE.length is : "+extensions.length);
        dirContent = RIO.getDirContent(loadedDirectory, extensions);
        choicesArea.setListData(RIO.getNames(dirContent));
    }
    /*
    public void setTable(){
        tableData = CRI.crittersTable(false);
        critterTable.setModel(new CritterTableModel(tableData));
    }

    public void stepUp(){
        if(iRun.islandStep()){
            iFrame.repaintIsland();
            time.setText("Time: "+iRun.getTime());
            logBox.setText(iRun.getLog());
            pausedboolean = true;
            start.setEnabled(false);
            JOptionPane.showMessageDialog(null,"Extinction event: The entire island population has died out."+"\nThe simulation is now closed.");
        }
        iFrame.repaintIsland();
        //TER = iRun.getTER();
        //CRI = iRun.getCRI();
        //iFrame.setTER(TER);
        //iFrame.setCRI(CRI);
        time.setText("Time: "+iRun.getTime());
        logBox.setText(iRun.getLog());
        sunset.setValue(progress); //Set the progress bar to the current % of day
        progress=progress+1; //progress the day
    }
    
    public void setSelectedRow(int critterID){
        if(critterID!=-1){ //If it's -1, don't set a row
            String IDStri = critterID+""; //Define the target
            for(int i=0; i<tableData.length ; i++){ //Iterate through the table data
                String dataStri = tableData[i][0].toString(); //The the iteration to compare
                if(dataStri.equals(IDStri)){ //Is the ID string in the data
                    critterTable.setRowSelectionInterval(i, i); //Select the rows between i and i
                    break;
                }
            }
        }
    }
    public void setSelectedCritter(int critterID){
        CRI.setTrackCRI(critterID);
        if(critterID!=-1){
            iFrame.setCRI(CRI);
        }
    }
    
    public void setTER(){
        iFrame.setTER(TER);
        iRun.setTER(TER);
        stepUp();
    }
    
    class CritterTableModel extends AbstractTableModel {
        private String[] columnNamesMod = {"Critter #","Sex","Health","X","Y"};
        private Object[][] dataMod = tableData;
        public CritterTableModel(Object[][] dataIN){dataMod = dataIN;}
        public int getColumnCount() {return columnNamesMod.length;}
        public int getRowCount() {return dataMod.length;}
        public String getColumnName(int col) {return columnNamesMod[col];}
        
        public Object getValueAt(int row, int col) {
            if(dataMod.length<=row){return -1;}
            else if(dataMod[0].length<=col){return-1;}
            else{return dataMod[row][col];}
        }
        
        public Class getColumnClass(int c) {return getValueAt(0, c).getClass();}
        public void setValueAt(Object value, int row, int col) {
            dataMod[row][col] = value;
            fireTableCellUpdated(row, col);
        }
    } */
}
